local Gladius = _G.Gladius
if not Gladius then
	DEFAULT_CHAT_FRAME:AddMessage(format("Module %s requires Gladius", "Highlight"))
end
local L = Gladius.L
local LSM

-- global functions
local strfind = string.find
local pairs = pairs
local GetRealNumRaidMembers, GetPartyAssignment, GetRaidTargetIndex = GetRealNumRaidMembers, GetPartyAssignment, GetRaidTargetIndex
local UnitGUID = UnitGUID

local Highlight = Gladius:NewModule("Highlight", false, false, {
	highlightHover = true,
	highlightHoverColor = {r = 1.0, g = 1.0, b = 1.0, a = 1.0},
	highlightTarget = true,
	highlightTargetColor = {r = 1, g = .7, b = 0, a = 1},
	highlightTargetPriority = 10,
	highlightFocus = true,
	highlightFocusColor = {r = 1, g = 0, b = 0, a = 1},
	highlightFocusPriority = 0,
	highlightAssist = true,
	highlightAssistColor = {r = 0, g = 1, b = 0, a = 1},
	highlightAssistPriority = 9,
	highlightRaidIcon1 = false,
	highlightRaidIcon1Color = {r = 1, g = 1, b = 0, a = 1},
	highlightRaidIcon1Priority = 8,
	highlightRaidIcon2 = false,
	highlightRaidIcon2Color = {r = 1, g = 0.55, b = 0, a = 1},
	highlightRaidIcon2Priority = 7,
	highlightRaidIcon3 = false,
	highlightRaidIcon3Color = {r = 1, g = 0.08, b = 0.58, a = 1},
	highlightRaidIcon3Priority = 6,
	highlightRaidIcon4 = false,
	highlightRaidIcon4Color = {r = 0.13, g = 0.55, b = 0.13, a = 1},
	highlightRaidIcon4Priority = 5,
	highlightRaidIcon5 = false,
	highlightRaidIcon5Color = {r = 0.86, g = 0.86, b = 0.86, a = 1},
	highlightRaidIcon5Priority = 4,
	highlightRaidIcon6 = false,
	highlightRaidIcon6Color = {r = 0.12, g = 0.56, b = 1.0, a = 1},
	highlightRaidIcon6Priority = 3,
	highlightRaidIcon7 = false,
	highlightRaidIcon7Color = {r = 1, g = 0.27, b = 0, a = 1},
	highlightRaidIcon7Priority = 2,
	highlightRaidIcon8 = false,
	highlightRaidIcon8Color = {r = 1, g = 1, b = 1, a = 1},
	highlightRaidIcon8Priority = 1,
})

function Highlight:OnEnable()
	self:RegisterEvent("UNIT_TARGET")
	self:RegisterEvent("PLAYER_FOCUS_CHANGED", "UNIT_TARGET")
	self:RegisterEvent("PLAYER_TARGET_CHANGED", "UNIT_TARGET")
	LSM = Gladius.LSM
	-- frame
	if (not self.frame) then
	self.frame = { }
	end
end

function Highlight:OnDisable()
	for unit in pairs(self.frame) do
		self.frame[unit]:SetAlpha(0)
	end
end

function Highlight:GetAttachTo()
	return ""
end

function Highlight:GetFrame(unit)
	return ""
end

function Highlight:UNIT_TARGET(event, unit)
	local unit = unit or ""
	if (unit ~= "" and ((not IsInRaid()) or strfind(unit, "pet") or (not strfind(unit, "raid") and not strfind(unit, "party")))) then
		return
	end
	local playerTargetGUID = UnitGUID("target")
	local focusGUID = UnitGUID("focus")
	local targetGUID = UnitGUID(unit.."target")
	for arenaUnit, frame in pairs(self.frame) do
		-- reset
		self:Reset(arenaUnit)
		if (targetGUID and UnitGUID(arenaUnit) == targetGUID and unit ~= "") then 
			-- main assist
			if (Gladius.db.highlightAssist and GetPartyAssignment("MAINASSIST", unit) == 1) then
				if (frame.priority < Gladius.db.highlightTargetPriority) then
					frame.priority = Gladius.db.highlightTargetPriority
					frame:SetBackdropBorderColor(Gladius.db.highlightTargetColor.r, Gladius.db.highlightTargetColor.g, Gladius.db.highlightTargetColor.b, Gladius.db.highlightTargetColor.a)
				end
			end
			-- raid target icon
			local icon = GetRaidTargetIndex(unit)
			if (icon and Gladius.db["highlightRaidIcon"..icon]) then
				if (frame.priority < Gladius.db["highlightRaidIcon"..icon.."Priority"]) then
					frame.priority = Gladius.db["highlightRaidIcon"..icon.."Priority"]
					frame:SetBackdropBorderColor(Gladius.db["highlightRaidIcon"..icon.."Color"].r, Gladius.db["highlightRaidIcon"..icon.."Color"].g, Gladius.db["highlightRaidIcon"..icon.."Color"].b, Gladius.db["highlightRaidIcon"..icon.."Color"].a)
				end
			end
		end
		-- focus
		if (focusGUID and UnitGUID(arenaUnit) == focusGUID) then
			if (frame.priority < Gladius.db.highlightFocusPriority) then
				frame.priority = Gladius.db.highlightFocusPriority
				frame:SetBackdropBorderColor(Gladius.db.highlightFocusColor.r, Gladius.db.highlightFocusColor.g, Gladius.db.highlightFocusColor.b, Gladius.db.highlightFocusColor.a)
			end
		end
		-- player target
		if (playerTargetGUID and UnitGUID(arenaUnit) == playerTargetGUID) then
			if (frame.priority < Gladius.db.highlightTargetPriority) then
				frame.priority = Gladius.db.highlightTargetPriority
				frame:SetBackdropBorderColor(Gladius.db.highlightTargetColor.r, Gladius.db.highlightTargetColor.g, Gladius.db.highlightTargetColor.b, Gladius.db.highlightTargetColor.a)
			end
		end
	end
end

function Highlight:CreateFrame(unit)
	local button = Gladius.buttons[unit]
	if (not button) then
		return
	end
	-- create frame
	self.frame[unit] = CreateFrame("Frame", "Gladius"..self.name..unit, button)
	-- set priority
	self.frame[unit].priority = - 1
end

function Highlight:Update(unit)
	-- create frame
	if (not self.frame[unit]) then
		self:CreateFrame(unit)
	end
	-- update frame 
	local left, right, top, bottom = Gladius.buttons[unit]:GetHitRectInsets()
	self.frame[unit]:ClearAllPoints()
	self.frame[unit]:SetPoint("TOPLEFT", Gladius.buttons[unit], "TOPLEFT", left - 3, top + 3)
	self.frame[unit]:SetWidth(Gladius.buttons[unit]:GetWidth() + abs(left) + abs(right) + 3)
	self.frame[unit]:SetHeight(Gladius.buttons[unit]:GetHeight() + abs(bottom) + abs(top) + 3)
	self.frame[unit]:SetBackdrop({edgeFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeSize = 1,})
	self.frame[unit]:SetBackdropBorderColor(0, 0, 0, 0)
	self.frame[unit]:SetFrameStrata("LOW")
	-- update highlight
	local button = Gladius.buttons[unit]
	local secure = button.secure
	if (Gladius.db.highlightHover) then
		-- set scripts
		button:SetScript("OnEnter", function(f, motion)
			if (motion and f:GetAlpha() > 0) then
				for _, m in pairs(Gladius.modules) do
					if (m:IsEnabled() and m.frame and m.frame[unit].highlight) then
						-- set color
						m.frame[unit].highlight:SetVertexColor(Gladius.db.highlightHoverColor.r, Gladius.db.highlightHoverColor.g, Gladius.db.highlightHoverColor.b, Gladius.db.highlightHoverColor.a)
						-- set alpha
						m.frame[unit].highlight:SetAlpha(0.5)
					end
				end
			end
		end)
		button:SetScript("OnLeave", function(f, motion)
			if (motion) then
				for _, m in pairs(Gladius.modules) do
					if (m:IsEnabled() and m.frame and m.frame[unit].highlight) then
						m.frame[unit].highlight:SetAlpha(0)
					end
				end
			end
		end)
		secure:SetScript("OnEnter", function(f, motion)
			if (motion and f:GetAlpha() > 0) then
				for _, m in pairs(Gladius.modules) do
					if (m:IsEnabled() and m.frame and m.frame[unit].highlight) then
						-- set color
						m.frame[unit].highlight:SetVertexColor(Gladius.db.highlightHoverColor.r, Gladius.db.highlightHoverColor.g, Gladius.db.highlightHoverColor.b, Gladius.db.highlightHoverColor.a)
						-- set alpha
						m.frame[unit].highlight:SetAlpha(0.5)
					end
				end
			end
		end)
		secure:SetScript("OnLeave", function(f, motion)
			if (motion) then
				for _, m in pairs(Gladius.modules) do
					if (m:IsEnabled() and m.frame and m.frame[unit].highlight) then
						m.frame[unit].highlight:SetAlpha(0)
					end
				end
			end
		end)
	else
		button:SetScript("OnEnter", nil)
		button:SetScript("OnLeave", nil)
		secure:SetScript("OnEnter", nil)
		secure:SetScript("OnLeave", nil)
	end
	-- hide
	self.frame[unit]:SetAlpha(0)
end

function Highlight:Show(unit)
	-- show
	self.frame[unit]:SetAlpha(1)
	local left, right, top, bottom = Gladius.buttons[unit]:GetHitRectInsets()
	self.frame[unit]:ClearAllPoints()
	self.frame[unit]:SetPoint("TOPLEFT", Gladius.buttons[unit], "TOPLEFT", left - 3, top + 3)
	self.frame[unit]:SetWidth(Gladius.buttons[unit]:GetWidth() + abs(left) + abs(right) + 3)
	self.frame[unit]:SetHeight(Gladius.buttons[unit]:GetHeight() + abs(bottom) + abs(top) + 3)
end

function Highlight:Reset(unit)
	if (not self.frame[unit]) then
		return
	end
	-- set priority
	self.frame[unit].priority = - 1
	-- hide border
	self.frame[unit]:SetBackdropBorderColor(0, 0, 0, 0)
end

function Highlight:Test(unit)
	-- test
end

function Highlight:GetOptions()
	local options = {
		general = {
			type = "group",
			name = L["General"],
			order = 1,
			args = {
				hover = {
					type = "group",
					name = L["Hover"],
					desc = L["Hover settings"],
					inline = true,
					order = 1,
					args = {
						highlightHover = {
							type = "toggle",
							name = L["Highlight On Mouseover"],
							desc = L["Highlight frame on mouseover"],
							disabled = function()
								return not Gladius.dbi.profile.modules[self.name]
							end,
							order = 5,
						},
						highlightHoverColor = {
							type = "color",
							name = L["Highlight Color"],
							desc = L["Color of the highlight frame"],
							hasAlpha = true,
							get = function(info)
								return Gladius:GetColorOption(info)
							end,
							set = function(info, r, g, b, a)
								return Gladius:SetColorOption(info, r, g, b, a)
							end,
							disabled = function()
								return not Gladius.dbi.profile.modules[self.name]
							end,
							order = 10,
						},
					},
				},
				target = {
					type = "group",
					name = L["Player Target"],
					desc = L["Player target settings"],
					inline = true,
					order = 2,
					args = {
						highlightTarget = {
							type = "toggle",
							name = L["Highlight Target"],
							desc = L["Show border around player target"],
							disabled = function()
								return not Gladius.dbi.profile.modules[self.name]
							end,
							order = 5,
						},
						highlightTargetColor = {
							type = "color",
							name = L["Highlight Target Color"],
							desc = L["Color of the target border"],
							hasAlpha = true,
							get = function(info)
								return Gladius:GetColorOption(info)
							end,
							set = function(info, r, g, b, a)
								return Gladius:SetColorOption(info, r, g, b, a)
							end,
							disabled = function()
								return not Gladius.dbi.profile.modules[self.name]
							end,
							order = 10,
						}, 
						highlightTargetPriority = {
							type = "range",
							name = L["Highlight Target Priority"],
							desc = L["Priority of the target border"],
							min = 0, max = 10, step = 1,
							disabled = function()
								return not Gladius.dbi.profile.modules[self.name]
							end,
							hidden = function()
								return not Gladius.db.advancedOptions
							end,
							width = "double",
							order = 15,
						},
					},
				},
				focus = {
					type = "group",
					name = L["Player Focus Target"],
					desc = L["Player focus target settings"],
					inline = true,
					order = 2,
					args = {
						highlightFocus = {
							type = "toggle",
							name = L["Highlight Focus Target"],
							desc = L["Show border around player target"],
							disabled = function()
								return not Gladius.dbi.profile.modules[self.name]
							end,
							order = 5,
						},
						highlightFocusColor = {
							type = "color",
							name = L["Highlight Focus Target Color"],
							desc = L["Color of the focus target border"],
							hasAlpha = true,
							get = function(info)
								return Gladius:GetColorOption(info)
							end,
							set = function(info, r, g, b, a)
								return Gladius:SetColorOption(info, r, g, b, a)
							end,
							disabled = function()
								return not Gladius.dbi.profile.modules[self.name]
							end,
							order = 10,
						},
						highlightFocusPriority = {
							type = "range",
							name = L["Highlight Focus Target Priority"],
							desc = L["Priority of the focus target border"],
							min = 0, max = 10, step = 1,
							disabled = function()
								return not Gladius.dbi.profile.modules[self.name]
							end,
							hidden = function()
								return not Gladius.db.advancedOptions
							end,
							width = "double",
							order = 15,
						},
					},
				},
				assist = {
					type = "group",
					name = L["Raid Assist Target"],
					desc = L["Raid assist settings"],
					inline = true,
					order = 2,
					args = {
						highlightAssist = {
							type = "toggle",
							name = L["Highlight Raid Assist"],
							desc = L["Show border around raid assist"],
							disabled = function()
								return not Gladius.dbi.profile.modules[self.name]
							end,
							order = 5,
						},
						highlightAssistColor = {
							type = "color",
							name = L["Highlight Raid Assist Color"],
							desc = L["Color of the raid assist border"],
							hasAlpha = true,
							get = function(info)
								return Gladius:GetColorOption(info)
							end,
							set = function(info, r, g, b, a)
								return Gladius:SetColorOption(info, r, g, b, a)
							end,
							disabled = function()
								return not Gladius.dbi.profile.modules[self.name]
							end,
							order = 10,
						},
						highlightAssistPriority = {
							type = "range",
							name = L["Highlight Raid Assist Priority"],
							desc = L["Priority of the raid assist border"],
							min = 0, max = 10, step = 1,
							disabled = function()
								return not Gladius.dbi.profile.modules[self.name]
							end,
							hidden = function()
								return not Gladius.db.advancedOptions
							end,
							width = "double",
							order = 15,
						},
					},
				},
			},
		},
		raidTargets = {
			type = "group",
			name = L["Raid Icon Targets"],
			hidden = function()
				return not Gladius.db.advancedOptions
			end,
			order = 2,
			args = { },
		},
	}
	-- raid targets
	for i = 1, 8 do
	options.raidTargets.args["raidTarget"..i] = {
		type = "group",
		name = "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_"..i..".blp:0|t"..L["Raid Icon Target "..i],
		desc = L["Raid Icon target "..i.." settings"], 
		inline = true,
		order = i,
		args = {
			highlightRaidIcon = {
				type = "toggle",
				name = L["Highlight Raid Target "..i],
				desc = L["Show border around raid target "..i],
				disabled = function()
					return not Gladius.dbi.profile.modules[self.name]
				end,
				arg = "highlightRaidIcon"..i,
				order = 5,
			},
			highlightRaidIconColor = {
				type = "color",
				name = L["Highlight Raid Assist Color"],
				desc = L["Color of the raid assist border"],
				hasAlpha = true,
				get = function(info)
					return Gladius:GetColorOption(info)
				end,
				set = function(info, r, g, b, a)
					return Gladius:SetColorOption(info, r, g, b, a)
				end,
				disabled = function()
					return not Gladius.dbi.profile.modules[self.name]
				end,
				arg = "highlightRaidIcon"..i.."Color",
				order = 10,
			},
			highlightRaidIconPriority = {
				type = "range",
				name = L["Highlight Raid Assist Priority"],
				desc = L["Priority of the raid assist border"],
				min = 0, max = 10, step = 1,
				disabled = function()
					return not Gladius.dbi.profile.modules[self.name]
				end,
				hidden = function()
					return not Gladius.db.advancedOptions
				end,
				arg = "highlightRaidIcon"..i.."Priority",
				width = "double",
				order = 15,
			},
		},
	}
	end
	return options
end